<template>
  <div
    class="axis-label-editor"
    :class="classAxisLabelEditor"
  >
    <el-button
      type="primary"
      class="btn-sure"
      size="default"
      @click="openEditor"
    >{{ btnText }}</el-button>
    <el-dialog
      v-model="editorVisiable"
      :title="btnText"
      width="600px"
      :close-on-click-modal="false"
      append-to-body
      :class="`${customClass} ${visualThemeClassName} axis-label-editor-dialog ${xvueNameSpace}`"
      @close="cancelEditor"
    >
      <el-form
        ref="form"
        class="form"
        :model="labelConf"
        :rules="rules"
      >
        <div class="inner">
          <div class="help_info">
            <table>
              <tr>
                <th>{{ $demoi18n('panel.explain') }}</th>
                <th>{{ _var }}{{ $demoi18n('panel.axisLabelEditor.passValue') }}</th>
                <th>{{ $demoi18n('panel.axisLabelEditor.editFormat') }}</th>
              </tr>
              <tr>
                <td>{{ $demoi18n('word.singleValue') }}</td>
                <td>"{{ _var }}":"100"</td>
                <td>{{ V() }}</td>
              </tr>
              <tr>
                <td>{{ $demoi18n('word.multiValue') }}</td>
                <td>"{{ _var }}":"name,job,age"</td>
                <td>
                  {{ V(0) }},{{ V(1) }},{{ V(2) }}
                  <br />
                  {{ V(0) }}-{{ V(1) }}-{{ V(2) }}
                </td>
              </tr>
            </table>
          </div>
          <VsFormItem prop="tpl">
            <el-input
              v-model="labelConf.tpl"
              type="textarea"
              :placeholder="$demoi18n('panel.axisLabelEditor.plsInput')"
            ></el-input>
          </VsFormItem>
          <table class="rich_table">
            <tr>
              <th>{{ $demoi18n('word.variable') }}</th>
              <th>{{ $demoi18n('word.color') }}</th>
              <th>{{ $demoi18n('panel.label.width') }}</th>
              <th>{{ $demoi18n('word.alignment') }}</th>
            </tr>
            <tr
              v-for="key in richKeys"
              v-show="tplHasKey(key)"
              :key="key"
            >
              <td>{{ getDisplayKey(key) }}</td>
              <td>
                <el-color-picker
                  v-model="labelConf.rich[key].color"
                  :popper-class="'vis-color-picker-panel-' + xvueTheme"
                  size="default"
                  color-format="hex"
                  append-to=".axis-label-editor-dialog"
                ></el-color-picker>
              </td>
              <td>
                <div class="td_inner">
                  <Range
                    v-if="labelConf.rich[key]._hasWidth"
                    v-model:value="labelConf.rich[key].width"
                    :min="1"
                    :max="1000"
                    type="input"
                    style="margin-right:10px"
                  />
                  <el-switch v-model="labelConf.rich[key]._hasWidth"></el-switch>
                </div>
              </td>
              <td>
                <div class="td_inner">
                  <el-select
                    v-model="labelConf.rich[key].align"
                    :class="'panel-data-select-' + xvueTheme"
                    :popper-class="'select-poper-' + xvueTheme"
                    size="default"
                    style="width: 80px;"
                  >
                    <el-option
                      :label="$demoi18n('option.align.left')"
                      value="left"
                    ></el-option>
                    <el-option
                      :label="$demoi18n('option.align.right')"
                      value="right"
                    ></el-option>
                    <el-option
                      :label="$demoi18n('option.align.center')"
                      value="center"
                    ></el-option>
                  </el-select>
                </div>
              </td>
            </tr>
          </table>
        </div>
      </el-form>
      <template #footer>
        <span>
          <el-button
            class="button-cancel"
            size="default"
            @click="cancelEditor"
          >{{ $demoi18n('btn.cancel') }}</el-button>
          <el-button
            class="btn-sure"
            size="default"
            type="primary"
            @click="saveLabel"
          >{{ $demoi18n('btn.confirm') }}</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import Range from '@/components/common/range/range.vue';
import { $demoi18n } from '@/utils/lang';
import { generateRules } from '@/utils/rules';
import { matchAll } from '@/utils/util.js';

export default {
  components: { Range },
  emits: ['save'],
  props: {
    btnText: {
      type: String,
      default: $demoi18n('panelProperty.btn.editVerticalAxisLabel'),
    },
    var: {
      type: String,
      default: 'y',
    },
    conf: {
      type: Object,
      default: () => ({
        tpl: '$_{y}'.replace('_', ''),
        rich: {},
      }),
    },
    property: Object, // 对应具体组件的config.property
  },
  data() {
    const dfRich = this.getDfRich();
    return {
      xvueNameSpace: process.env.xvueNameSpace, // 给挂载在body下的元素加上主类名
      editorVisiable: false,
      labelConf: {
        tpl: '$_{y}'.replace('_', ''),
        rich: {
          v: dfRich,
        },
      },
      classAxisLabelEditor: `axis-label-editor-${window._adoPremise.uc.theme || 'light'}`,
      customClass: `vs_axis_label_editor_popup vs_axis_label_editor_popup-${window._adoPremise.uc.theme || 'light'}`,
      xvueTheme: window._adoPremise.uc.theme, // 'dark',
      rules: {
        tpl: generateRules({
          required: false,
        }),
      },
    };
  },
  computed: {
    richKeys() {
      const keys = Object.keys(this.labelConf.rich);
      keys.sort();
      return keys;
    },
    _var() {
      return this.var;
    },
  },
  watch: {
    conf(newConf) {
      this.initLabelConf();
    },
    'labelConf.tpl'() {
      this.setRich();
    },
  },
  created() {
    this.initLabelConf();
  },
  methods: {
    initLabelConf() {
      const dfTpl = `\${${this.var}}`;
      let conf = {};
      if (this.conf) {
        conf = JSON.parse(JSON.stringify(this.conf));
      }

      if (!conf.tpl) {
        conf.tpl = dfTpl;
      }
      if (!conf.rich) {
        conf.rich = {
          [this.var]: this.getDfRich(),
        };
      }
      this.labelConf = conf;
    },

    V(num = false) {
      const v = this.var;
      if (num === false) {
        return `\${${v}}`;
      } else {
        return `\${${v}[${num}]}`;
      }
    },

    getDfRich() {
      const { componentStyle } = this.property || {};
      const color = componentStyle === 'dark' ? '#8995a0' : '#999999';
      return {
        color: color,
        width: 50,
        align: 'right',
        _hasWidth: false,
      };
    },

    setRich() {
      const { tpl, rich } = this.labelConf;
      let keysArr = [];
      const v = this.var;

      const hasV = tpl.includes(`\${${v}}`);
      if (hasV) {
        keysArr.push(v);
      }

      const rex = new RegExp(`${v}\\[(\\d+)\\]`, 'g');
      let arr = matchAll(tpl, rex, 1);
      arr = Array.from(new Set(arr)).map(n => v + n);

      keysArr = [...keysArr, ...arr]; // 例如：['y', 'y0', 'y1']

      keysArr.forEach(key => {
        if (!rich[key]) {
          rich[key] = this.getDfRich();
        }
      });

      this.labelConf.rich = JSON.parse(JSON.stringify(rich));
    },

    tplHasKey(key) {
      const v = this.var;
      const { tpl } = this.labelConf;
      if (key === v) {
        return tpl.includes(`\${${v}}`);
      }
      const _key = this.getDisplayKey(key);
      if (_key && tpl.includes(_key)) {
        return true;
      }
      return false;
    },

    getDisplayKey(key) {
      const v = this.var;
      if (key === v) {
        return v;
      }
      const rex = new RegExp(`^${v}\\d+$`);
      if (rex.test(key)) {
        const num = key.replace(v, '');
        const _key = `${v}[${num}]`;
        return _key;
      }
      return '';
    },

    openEditor() {
      this.editorVisiable = true;
    },
    cancelEditor() {
      this.editorVisiable = false;
    },
    saveLabel() {
      this.$refs.form.validate(valid => {
        if (!valid) {
          return;
        }
        this.editorVisiable = false;
        const _conf = JSON.parse(JSON.stringify(this.labelConf));
        this.$emit('save', _conf);
      });
    },
  },
};
</script>
<style lang="less">
@import '../../../common/color-picker-panel.less';
</style>

<style lang="less" scoped>
.axis-label-editor {
}

.axis-label-editor-dark {
  .btn-sure {
    background-color: #0eb4c2;
    border-color: #0eb4c2;
    color: #fff;

    .el-icon-circle-plus {
      color: #fff;
    }
  }
}
</style>
<style lang="less">
.vs_axis_label_editor_popup {
  .help_info {
    border: 1px solid #ddd;
    background-color: #efefef;
    table {
      border-collapse: collapse;
      width: 100%;
      th,
      td {
        font-size: 11px;
        padding: 5px 10px;
        font-weight: normal;
      }
      th {
        text-align: left;
        background-color: #ddd;
      }
      td {
        vertical-align: top;
      }
    }
  }
  .el-textarea {
    margin-top: 10px;
    font-size: 11px;
    textarea {
      padding-left: 10px;
      height: 100px;
    }
  }
  .rich_table {
    margin-top: 10px;
    width: 100%;
    border-collapse: collapse;
    th,
    td {
      padding: 5px;
      border: 1px solid #ddd;
      text-align: center;
    }
    td {
      .el-color-picker {
        vertical-align: middle;
      }
      .td_inner {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }
}
</style>

<style lang="less">
@borderColor_dark: #116584;
@textColor_dark: #ffffff;
@bgColor_dark: #000c17;
.vs_axis_label_editor_popup-dark {
  .el-dialog__header {
    background: #183c5a;
    .el-dialog__title {
      color: #fff;
    }

    .el-dialog__headerbtn {
      .el-dialog__close {
        color: #fff;
      }
    }
  }

  .el-dialog__body {
    background: #0e2b40;

    .inner {
      .help_info {
        border-color: @borderColor_dark;
        background-color: #122b40;

        table {
          tr {
            th {
              background-color: #122b40;
              border-color: #122b40;
              color: #00f0ff;
            }
            td {
              background-color: #122b40;
              border-color: #122b40;
              color: #98cae6;
            }
          }
        }
      }

      .el-textarea {
        textarea {
          background-color: rgba(53, 83, 107, 0.7);
          border-color: @borderColor_dark;
          color: #fff;
        }
      }

      .rich_table {
        tr {
          th {
            background-color: #122b40;
            border-color: @borderColor_dark;
            color: #00f0ff;
          }
          td {
            background-color: #122b40;
            border-color: @borderColor_dark;
            color: #98cae6;
          }
        }

        .el-color-picker {
          .el-color-picker__trigger {
            border-color: @borderColor_dark;
          }
        }

        .input-number {
          .el-input-number__decrease {
            background-color: #000c17;
            border-color: #116584;
            color: #116584;
          }

          .el-input-number__increase {
            background-color: #000c17;
            border-color: #116584;
            color: #116584;
          }
        }

        .el-input {
          .el-input__inner {
            border-color: @borderColor_dark;
            color: @textColor_dark;
            background-color: @bgColor_dark;
          }

          .el-input__icon {
            color: @borderColor_dark;
          }
        }

        .el-switch__core {
          background-color: #064559;
          border-color: #064559;
        }

        .el-switch.is-checked {
          .el-switch__core {
            background-color: #0eb4c2;
            border-color: #0eb4c2;
          }
        }
      }
    }
  }
  .el-dialog__footer {
    background: #0e2b40;
    .btn-sure {
      background-color: #0eb4c2;
      border-color: #0eb4c2;
      color: #fff;

      .el-icon-circle-plus {
        color: #fff;
      }
    }

    .button-cancel {
      background-color: #064559;
      border-color: #064559;
      color: #fff;

      .el-icon-circle-plus {
        color: #fff;
      }
    }
  }
}
</style>
